package draw.impl;

/**
 * A point represents a location with respect to some set of axis.
 * It is immutable and has basic calculations for finding distance
 * between objects, or the difference w.r.t. one set of axis.
 *
 * @author Matthew B. Gray <matthew.b.gray@gmail.com>
 * @version 1.0
 */
public class Point implements Comparable {
	protected Integer x,y;

	public Integer getX() { return x; }
	public Integer getY() { return y; }
	/** Is that north of this? */
	public boolean isNorth(Point that) { return this.y < that.y; }
	/** Is that south of this? */
	public boolean isSouth(Point that) { return this.y > that.y; }
	/** Is that east of this? */
	public boolean isEast(Point that) { return this.x < that.x; }
	/** Is that west of this? */
	public boolean isWest(Point that) { return this.x > that.x; }

	public Point(Integer x, Integer y) {
		this.x = x;
		this.y = y;
	}

	public Double distanceFrom(Point that) {
		return Math.abs(
			Math.sqrt(this.differenceInX(that)^2
					+ this.differenceInY(that)^2)
		);
	}

	public String toString() {
		return new StringBuffer('(')
			.append(x.toString())
			.append(',')
			.append(')').toString();
	}

	public boolean equals(Object obj) {
		Point that = (Point)obj;
		return this.x.equals(that.x) && this.y.equals(that.y);
	}

	public int compareTo(Object obj) {
		Point that = (Point)obj;
		int toReturn;

		if(this.equals(that))
			toReturn = 0; // equal
		else if(this.isNorth(that) && this.isEast(that))
			toReturn = 2; // north-east (upper right)
		else if(this.isNorth(that) && this.isWest(that))
			toReturn = 1; // north west (upper left)
		else if(this.isSouth(that) && this.isEast(that))
			toReturn = -1;
		else
			toReturn = -2;

		return toReturn;
	}

	protected Integer differenceInX(Point that) {
		return Math.abs(this.getX() - that.getX());
	}

	protected Integer differenceInY(Point that) {
		return Math.abs(this.getY() - that.getY());
	}
}
